﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InstallManager.Msi
{
    internal class MsiDataReader : IDisposable
    {
        private MsiCommand _command;

        private bool _disposed;

        private IntPtr _record;

        internal MsiDataReader(MsiCommand command)
        {
            this._command = command;
        }

        private void CheckDisposed()
        {
            if (this._disposed)
            {
                throw new ObjectDisposedException("MSI");
            }
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!this._disposed && this._record != IntPtr.Zero)
            {
                MsiDbInterop.MsiCloseHandle(this._record);
                this._record = IntPtr.Zero;
                this._disposed = true;
            }
        }
        
        public int GetInteger(uint column)
        {
            this.CheckDisposed();
            if (this._record == IntPtr.Zero)
            {
                throw new Exception("No record fetched.");
            }
            column++;
            int num = MsiDbInterop.MsiRecordGetInteger(this._record, column);
            return num;
        }

        public string GetString(uint column)
        {
            this.CheckDisposed();
            if (this._record == IntPtr.Zero)
            {
                throw new Exception("No record fetched.");
            }
            column++;
            StringBuilder stringBuilder = new StringBuilder("", 1);
            int capacity = 0;
            uint num1 = MsiDbInterop.MsiRecordGetString(this._record, column, stringBuilder, ref capacity);
            if (num1 == 234)
            {
                stringBuilder.Capacity = capacity++;
                num1 = MsiDbInterop.MsiRecordGetString(this._record, column, stringBuilder, ref capacity);
            }
            if (num1 != 0)
            {
                throw new Exception(string.Concat("Failed to read string. Error code = ", num1));
            }
            return stringBuilder.ToString();
        }

        public bool Read()
        {
            uint num;
            this.CheckDisposed();
            if (this._command.Handle == IntPtr.Zero)
            {
                throw new Exception("Command not ready.");
            }
            if (this._record == IntPtr.Zero)
            {
                num = MsiDbInterop.MsiViewExecute(this._command.Handle, IntPtr.Zero);
                if (num != 0)
                {
                    throw new Exception(string.Concat("Failed to run command. Error code = ", num));
                    MsiDbInterop.MsiCloseHandle(this._record);
                }
            }
            num = MsiDbInterop.MsiViewFetch(this._command.Handle, out this._record);
            if (num == 259)
            {
                return false;
            }
            if (num != 0)
            {
                throw new Exception(string.Concat("Failed to get record. Error code = ", num));
            }
            return true;
        }
    }
}
